include “stdafx.h”
include < iostream >
include < stdlib.h >
include < stdio.h>
include < vector>
include < assert.h>
using namespace std;
/*
平衡二叉树(Self-Balacing binary tree): 又称为“AVL树”,此AVL不同于AVL算法!!!以下简称为“AVL树”。
“AVL树”是“BST树(Binary Search Tree)”的演变版本,也就是“AVL树”也是BST树!!!
"AVL树"由于它任意节点的左右子树的深度差的绝对值小等于1,且权值左孩子<父节点<右孩子等的特性,使得其查询和增、删节点的时间复杂度都为O(log2n)。即即使在最差
的情况下,它的搜索和增、删节点的效率也能达到log2n!!!!
AVL树的规范要求:
1. 左孩子<=父节点<=右孩子 (权值)
2. 此树中的任意节点的左右子树的深度差的绝对值<=1
AVL树的创建:
假设根节点为T增加一个节点a时:
1. 先判断T是否存在,如果不存在,设T = a
2. 将a先按BST树增加节点的方式增加
3. 从增加节点的父节点开始,判断此树的的左右子树的深度差的绝对值是否<=1,若>1,则执行4步骤
4. 通过“旋转”使该树重新达到平衡,旋转的次数为1次或多次!!设最开始出现不平衡的子树的根节点的root的旋转的种类有:
a. 右旋(R):左子树的深度高于右子树时,且左子树以及其子树的节点全部都仅存在于左边,如60、50、40,此时向右旋转一次即平衡
b. 左旋(L):右子树的深度高于左子树时,且右子树以及其子树的节点全部都仅存在于右边,如60、70、80,此时向左旋转一次即平衡
c. 左右旋(LR):左子树的深度高于右子树时,且新增节点a在root的左孩子的右孩子上,如60、40、50,此时先向左旋转一次得60、50、40,再向右旋转一次即平衡
d. 右左旋(RL):右子树的深度高于左子树时,且新增节点a在root的右孩子的左孩子上,如60、80、70,此时向右旋转一次得60、70、80,再向左旋转一次即平衡
AVL树删除节点:
先找到需要删除的节点,再根据需要删除节点node有无孩子节点和在删除node后的左右孩子的深度以及node的左右孩子的深度来判断(参考函数void deleteNode(int value))
1. 删除点为叶子节点
2. 删除的节点有左孩子
3. 删除的节点有右孩子
4. 删除的节点左右孩子都有
*/
struct Tree
{
int value; //权值
Tree* pLeft; //记录左子树节点
Tree* pRight; //记录右子树节点
Tree* pParent; //记录父节点
Tree* pEqualValue; //记录相同值的节点
int leftDeep; //记录左子树深度
int rightDeep; //记录右子树深度
Tree(int n)
{
value = n;
pLeft = NULL;
pRight = NULL;
pParent = NULL;
pEqualValue = NULL;
leftDeep = 0;
rightDeep = 0;
}
void AddEV(Tree* node)
{
//默认将值相同的节点全部放于左孩子!!
if (node == NULL)
{
return;
}
if (pEqualValue == NULL)
{
pEqualValue = node;
}
else
{
Tree* pTempNode = pEqualValue;
while(pTempNode->pLeft)
{
pTempNode = pTempNode->pLeft;
}
pTempNode->pLeft = node;
node->pParent = pTempNode;
}
}
~Tree()
{
cout << "释放内存: " << value << endl;
pLeft = NULL;
pRight = NULL;
pParent = NULL;
pEqualValue = NULL;
}
};
static vector< Tree*> m_rootTree;
static Tree* m_rootNode = NULL;
/*
Desc: 增加节点的深度
*/
void AddDeep(Tree* node)
{
Tree* pParent = node->pParent;
Tree* pChilde = node;
while (pParent != NULL)
{
if (pParent->pLeft == pChilde)
{
pParent->leftDeep = pChilde->leftDeep >= pChilde->rightDeep ? (pChilde->leftDeep + 1) : (pChilde->rightDeep + 1);
}
else if (pParent->pRight == pChilde)
{
pParent->rightDeep = pChilde->leftDeep >= pChilde->rightDeep ? (pChilde->leftDeep + 1) : (pChilde->rightDeep + 1);
}
pChilde = pParent;
pParent = pParent->pParent;
}
}
/*
Desc: 降低深度
*/
void subDeep(Tree* node)
{
Tree* pParent = node->pParent;
Tree* pChilde = node;
while (pParent != NULL)
{
if (pParent->pLeft == pChilde)
{
pParent->leftDeep = pChilde->leftDeep >= pChilde->rightDeep ? (pChilde->leftDeep + 1) : (pChilde->rightDeep + 1);
}
else if (pParent->pRight == pChilde)
{
pParent->rightDeep = pChilde->leftDeep >= pChilde->rightDeep ? (pChilde->leftDeep + 1) : (pChilde->rightDeep + 1);
}
pChilde = pParent;
pParent = pParent->pParent;
}
m_rootNode = pChilde;
}
/*
Desc: 右旋转
Param: node //要旋转的跟节点
*/
bool rotationRight(Tree* node)
{
Tree* c = node->pLeft;
Tree* b = c->pLeft;
Tree* a = node;
if ((a==NULL) || (b==NULL) || (c==NULL))
{
//assert(a && b && c);
return false;
}
Tree* tempRootNode = a->pParent;
c->pParent = tempRootNode;
if (tempRootN